package xgin

import (
	"math"
	"time"

	"github.com/gin-gonic/gin"
)

type Response struct {
	data any
}

// 返回Response结构体
func Resp() *Response {
	return &Response{}
}

// 成功返回的消息
//
//	data	gin.H类型变量返回
func (r *Response) Success(data gin.H) *Response {
	return r.Json(_succ(data))
}

// 任意类型变量返回
//
//	data	任意类型变量返回
func (r *Response) SuccessAny(data any) *Response {
	return r.Json(_succ(gin.H{"_": data}))
}

// 成功返回的消息
//
//	成功消息返回
func (r *Response) SuccessEmpty() *Response {
	return r.Json(_succ(gin.H{}))
}

// 一般错误返回消息
//
//	msg	错误消息返回
func (r *Response) Error(msg error) *Response {
	if msg == nil {
		return r.ErrorString(_default.CheckKeyDefaultMsg)
	}
	return r.ErrorString(msg.Error())
}

// 一般错误返回消息
//
//	msg	字符串类型的错误描述信息
func (r *Response) ErrorString(msg string) *Response {
	return r.Json(_error(_default.CheckKeyDefaultError, msg))
}

// 数据库错误
func (r *Response) ErrorDB() *Response {
	return r.Json(_error(_default.CheckKeyDB, _default.ErrorMsgDB))
}

// 查询数据为空
func (r *Response) ErrorEmpty() *Response {
	return r.Json(_error(_default.CheckKeyEmpty, _default.ErrorMsgEmpty))
}

// 授权错误
func (r *Response) ErrorAuth() *Response {
	return r.Json(_error(_default.CheckKeyAuth, _default.ErrorMsgAuth))
}

// 参数错误
func (r *Response) ErrorParam() *Response {
	return r.Json(_error(_default.CheckKeyParam, _default.ErrorMsgParam))
}

// 参数错误
//
//	err	参数验证模块返回的错误信息
func (r *Response) EP(err error) *Response {
	if err != nil {
		return r.Json(_error(_default.CheckKeyParam, err.Error()))
	}
	return r.ErrorParam()
}

// 登录错误
func (r *Response) ErrorLogin() *Response {
	return r.Json(_error(_default.CheckKeyNoLogin, _default.ErrorMsgNologin))
}

// 自定义错误信息返回
// 封装error信息的返回
//
//	code	返回的code值
//	msg		错误消息描述
func _error(code int, msg string) gin.H {
	m := gin.H{
		_default.CheckKey:    code,
		_default.CheckFlag:   false,
		_default.CheckMsgKey: msg,
		_default.RequestKey:  nil,
	}
	for i, v := range map_map(_default.ErrorMap) {
		m[i] = v
	}
	return m
}

// 自定义错误信息返回
//
//	data	返回值结构（如果返回值为gin.H{"_":xxxx}，则会直接将xxxx提取到data层级，以兼容any类型返回）
func _succ(data gin.H) gin.H {
	m := gin.H{
		_default.CheckKey:    _default.CheckKeySuccess,
		_default.CheckFlag:   true,
		_default.CheckMsgKey: _default.CheckKeySuccessMsg,
		_default.RequestKey:  data,
	}
	if v, ok := data["_"]; ok && len(data) == 1 {
		m[_default.RequestKey] = v
	}
	for i, v := range map_map(_default.SuccessMap) {
		m[i] = v
	}
	return m
}

// 格式化map对象中的部分值
//
//	maps	待转换的map数组
func map_map(maps map[string]any) map[string]any {
	for i, v := range maps {
		if vs, ok := v.(string); ok {
			switch vs {
			case "datetime":
				maps[i] = time.Now().Format(time.DateTime)
			case "date":
				maps[i] = time.Now().Format(time.DateOnly)
			case "time":
				maps[i] = time.Now().Format(time.TimeOnly)
			}
		}
	}
	return maps
}

// 返回JSON数据
//
//	data	整体结构返回
func (r *Response) Json(data gin.H) *Response {
	r.data = data
	return r
}

// Orm查询列表分页方式返回[直接使用len计算条数]
//
//	c	quest对象
//	lists	返回的列表数据
//	count	查询条数
//	exper	扩展字段
func (r *Response) NoPage(c *gin.Context, lists any, count int, exper ...any) *Response {
	return r.Page(c, lists, int64(count), exper...)
}

// Orm查询列表分页方式返回
//
//	c	quest对象
//	lists	返回的列表数据
//	count	查询条数
//	exper	扩展字段
func (r *Response) Page(c *gin.Context, lists any, count int64, exper ...any) *Response {
	if c == nil {
		return r.PageNoGC(1, 10, lists, count, exper...)
	}
	return r.PageNoGC(c.GetInt("_p0"), c.GetInt("_p1"), lists, count, exper...)
}

// Orm查询列表分页方式返回
//
//	page	当前页码
//	limit	每页条数
//	lists	返回的列表数据
//	count	查询条数
//	exper	扩展字段
func (r *Response) PageNoGC(page, limit int, lists any, count int64, exper ...any) *Response {
	pre_page := page - 1
	if pre_page <= 0 {
		pre_page = 1
	}
	if page <= 0 {
		page = 1
	}
	if count <= 0 {
		count = 0
	}
	if limit <= 0 {
		limit = 10
	}
	last_page := int(math.Ceil(float64(count) / float64(limit)))
	dat := gin.H{
		_default.Pages.TotalKeys: count,
		_default.Pages.ListKeys:  lists,
		_default.Pages.PagesKeys: map[string]any{
			_default.Pages.PagesCurrentKeys: page,
			_default.Pages.PagesLastKeys:    last_page,
			_default.Pages.PagesPerKeys:     pre_page,
			_default.Pages.PagesTotalKeys:   count,
			_default.Pages.PagesLimitKeys:   limit,
		},
	}
	if len(exper) > 0 {
		dat["exper"] = exper[0]
	}
	return r.Success(dat)
}

// 输出字符串内容
//
//	data	整体字符串输出
func (r *Response) String(data string) *Response {
	r.data = data
	return r
}

// 输出二进制内容
//
//	data	整体二进制输出
func (r *Response) Byte(data []byte) *Response {
	r.data = data
	return r
}

// 获取Data数据
func (r *Response) GetData() any {
	return r.data
}
